package com.example.easycharge.service;

import com.alibaba.fastjson.JSONObject;
import com.example.easycharge.entity.ChargePile;
import com.example.easycharge.entity.Customer;
import com.example.easycharge.entity.Vehicle;
import com.example.easycharge.error.BillNotFoundError;
import com.example.easycharge.entity.Bill;
import com.example.easycharge.repository.BillRepository;
import com.example.easycharge.repository.ChargePileRepository;
import com.example.easycharge.repository.CustomerRepository;
import com.example.easycharge.repository.VehicleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class BillService {

    @Autowired
    private VehicleRepository vehicleRepository;
    @Autowired
    private ChargePileRepository chargePileRepository;
    @Autowired
    private CustomerRepository customerRepository;
    @Autowired
    private BillRepository billRepository;

    // 峰值电价
    private double PEAK_PRICE = 1.0;
    // 谷值电价
    private double BOTTOM_PRICE = 0.4;
    // 正常电价
    private double NORMAL_PRICE = 0.7;
    // 服务费
    private double SERVICE_PRICE = 0.8;
    //  谷峰区间
    private String SECTION = "0000000" + "111" + "22222" + "111" + "222" + "11" + "0";
    private double overtimeMoneyPreHour = 1.2;
    private int tempNowHour = 6;
    private int nowPeak = 0;
    private final HashMap<Long, Bill> billMap = new HashMap<>();

    public void startBill(long vehicleId, long pileId, int chargePower) {
        Vehicle vehicle = vehicleRepository.findVehicleByVehicleId(vehicleId);
        ChargePile chargePile = chargePileRepository.findChargePileByChargePileId(pileId);
        long customerId = vehicle.getCustomerId();
        Customer customer = customerRepository.findCustomerByUserId(customerId);
        int mouthElectricity = customer.getMouthElectricity();
        double stepAdd = 0;
        if (mouthElectricity > 600) {
            stepAdd = 0.3;
        } else if (mouthElectricity > 260) {
            stepAdd = 0.05;
        }
        Bill bill = new Bill(vehicleId, customerId, pileId, chargePower, stepAdd);
        billMap.put(vehicleId, bill);
    }

    public Bill getBill(long vehicleId) {
        return billMap.getOrDefault(vehicleId, null);
    }

    // 每分钟执行一次
    public void addChargeBill(long vehicleId) {
        Bill bill = billMap.get(vehicleId);
        double chargePower = bill.getChargePower();
        double preBill;
        if (nowPeak == 0) {
            preBill = BOTTOM_PRICE;
        } else if (nowPeak == 1) {
            preBill = NORMAL_PRICE;
        } else {
            preBill = PEAK_PRICE;
        }
        // 每度电价格*千瓦时
        // 每度电价格*千瓦时
        double addMoney = preBill * (chargePower / 60);
        double serviceAddMoney = SERVICE_PRICE * (chargePower / 60);
        bill.chargeAdd(addMoney);
        bill.serviceAdd(serviceAddMoney);
        bill.chargeMinutesAdd(1);
    }

    // 开始充电
    public void startCharge(long vehicleId) throws BillNotFoundError {
        if (billMap.containsKey(vehicleId)) {
            Bill thisBill = billMap.get(vehicleId);
            thisBill.setCharging(true);
            thisBill.setStartChargeDate(new Date());
        } else {
            throw new BillNotFoundError();
        }
    }

    public void endCharge(long vehicleId) throws BillNotFoundError {
        if (billMap.containsKey(vehicleId)) {
            Bill thisBill = billMap.get(vehicleId);
            thisBill.setCharging(false);
            thisBill.setEndChargeDate(new Date());
        } else {
            throw new BillNotFoundError();
        }
    }

    public Bill endBill(long vehicleId) throws BillNotFoundError {
        if (billMap.containsKey(vehicleId)) {
            Bill thisBill = billMap.get(vehicleId);
            thisBill.setEndDate(new Date());
            billMap.remove(vehicleId);
            billRepository.save(thisBill);
            return thisBill;
        } else {
            throw new BillNotFoundError();
        }
    }

    public Collection<Bill> getAllBill() {
        return billMap.values();
    }

    public List<Bill> getAllBillByCustomerId(long customerId) {
        return billRepository.getBillsByCustomerId(customerId);
    }

    public List<Bill> getChargingBill(long customerId) {
        List<Bill> result = new ArrayList<>();
        // 代码不合理，但是懒得改了
        for (Bill bill : billMap.values()) {
            if (bill.getCustomerId() == customerId) {
                result.add(bill);
            }
        }
        return result;
    }

    // 用返回值来表示谷峰，2为峰，0为谷，1为平
    public int peakCheck(int nowHour) {
        nowHour = tempNowHour;
        if (nowHour > 23) {
            return 1;
        }
        /*
            section区间表示每个时刻是峰值还是谷值，
            比如000011112222就表示
            0-3点谷值，
            4-7点平值，
            8-11点峰值，诸如此类
        * */
        return SECTION.charAt(nowHour) - '0';
    }

    public void setPEAK_PRICE(double PEAK_PRICE) {
        this.PEAK_PRICE = PEAK_PRICE;
    }

    public void setBOTTOM_PRICE(double BOTTOM_PRICE) {
        this.BOTTOM_PRICE = BOTTOM_PRICE;
    }

    public void setNORMAL_PRICE(double NORMAL_PRICE) {
        this.NORMAL_PRICE = NORMAL_PRICE;
    }

    public void setSERVICE_PRICE(double SERVICE_PRICE) {
        this.SERVICE_PRICE = SERVICE_PRICE;
    }

    public void setSECTION(String SECTION) {
        this.SECTION = SECTION;
    }

    public double getPEAK_PRICE() {
        return PEAK_PRICE;
    }

    public double getBOTTOM_PRICE() {
        return BOTTOM_PRICE;
    }

    public double getNORMAL_PRICE() {
        return NORMAL_PRICE;
    }

    public double getSERVICE_PRICE() {
        return SERVICE_PRICE;
    }

    public String getSECTION() {
        return SECTION;
    }

    public double getOvertimeMoneyPreHour() {
        return overtimeMoneyPreHour;
    }

    public void setOvertimeMoneyPreHour(double overtimeMoneyPreHour) {
        this.overtimeMoneyPreHour = overtimeMoneyPreHour;
    }

    public JSONObject initBill() {
        JSONObject result = new JSONObject();
        tempNowHour = 6;
        result.put("Time", "已完成初始化");
        return result;
    }

    public void hourAdd() {
        tempNowHour++;
        nowPeak = peakCheck(tempNowHour);
    }

    public String getNowTime() {
        String nowTime = tempNowHour + ":";
        nowTime += peakCheck(tempNowHour);
        return nowTime;
    }
}
